class ConPlayerController extends UTPlayerController;

var bool bViewingOtherPlayer;

reliable client function PlayStartupMessage(byte StartupStage)
{
	if ( StartupStage == 7 )
	{
		ReceiveLocalizedMessage( class'ConTimerMessage', 17, PlayerReplicationInfo );
	}
	else
	{   
        ReceiveLocalizedMessage( class'ConStartupMessage', StartupStage, PlayerReplicationInfo );
	}
}

reliable server function ServerSetCharacterData(CustomCharData CharData)
{
	local UTPlayerReplicationInfo PRI;
	//local UTTeamInfo Team;
	//local class<UTFamilyInfo> FamilyInfoClass;

	PRI = UTPlayerReplicationInfo(PlayerReplicationInfo);
	if (PRI != None)
	{
		if ( UTGameReplicationInfo(WorldInfo.GRI).bStoryMode )
		{
			if ( PRI.SinglePlayerCharacterIndex < 0 )
			{
				UTGameReplicationInfo(WorldInfo.GRI).AssignSinglePlayerCharacters(PRI);
			}
			return;
		}

		PRI.SetCharacterData(CharData);
	}

	// force bots on player's team to be same faction
	/* if ((WorldInfo.NetMode == NM_Standalone || WorldInfo.NetMode == NM_ListenServer) && IsLocalPlayerController())
	{
		Team = UTTeamInfo(PlayerReplicationInfo.Team);
		if (Team != None)
		{
			FamilyInfoClass = class'UTCustomChar_Data'.static.FindFamilyInfo(CharData.FamilyID);
			if(FamilyInfoClass != None)
			{
				Team.Faction = FamilyInfoClass.default.Faction;
			}
		}
	}*/
}

// Kyle: Spectate system derived from BattleTeamArena
// Kyle: Begin Spectate System
state Dead
{
  exec function StartFire (optional byte FireModeNum)
  {
	  if (ConPRI (PlayerReplicationInfo).bRecentlyDead != true)
	  {
			ServerRestartPlayer();
	  }
	  else
	  {
	    if (FireModeNum==0) {
	      SpectateCycle();
	    } else {
	      SpectateMe();
	    }
	  }
  }
}

reliable server function SpectateMe() 
{
  if (Pawn != None) {
    if (bViewingOtherPlayer) ServerShowMessage (1, ConPRI (PlayerReplicationInfo));
    bViewingOtherPlayer = false;
    ConPRI(PlayerReplicationInfo).WeAreSpectating = ConPRI(PlayerReplicationInfo);
    SetViewTarget (Pawn);
  }
}

reliable server function SpectateCycle()
{
  local ConPRI CPRI;
  
  CPRI = NextInCycle (RealViewTarget, "spectate");
  if (CPRI != None && RealViewTarget != CPRI) {
    ServerShowMessage (1, CPRI);
    bViewingOtherPlayer = true;
    ConPRI(PlayerReplicationInfo).WeAreSpectating = CPRI;
    if (CPRI == PlayerReplicationInfo) {
      if (Pawn != None) {
        SetViewTarget (Pawn);
      } else {
        SetViewTarget (CPRI);
      }
    } else {
      SetViewTarget (CPRI);
    }
  }
}

function ConPRI NextInCycle (Actor Current, optional string CycleType="spectate", optional int Direction=1) {
  local int i, CurrentIndex, NewIndex;
  local ConPRI CPRI;

  // Determine the CPRI of what we are currently looking at
  if (Current == Pawn) {
    CPRI = ConPRI (PlayerReplicationInfo);
  } else {
    CPRI = ConPRI (Current);
  }

  // Locate current CPRI;
  CurrentIndex = -1;
  for (i=0; i<WorldInfo.GRI.PRIArray.Length; i++) {
    if (CPRI == WorldInfo.GRI.PRIArray[i]) {
      CurrentIndex = i;
      break;
    }
  }

  // Locate next CPRI
  for (NewIndex=CurrentIndex+Direction; (NewIndex>=0)&&(NewIndex<WorldInfo.GRI.PRIArray.Length); NewIndex=NewIndex+Direction) {
    CPRI = ConPRI (WorldInfo.GRI.PRIArray[NewIndex]);
    if (CPRI != None) {
      if (CycleType == "spectate" && (Controller(CPRI.Owner) != None) && CanSpectate(CPRI) && !CPRI.bOnlySpectator) {
        return CPRI;
      } else if (CycleType == "viewstats" && !CPRI.bOnlySpectator) {
        return CPRI;
      }
	}
  }
  CurrentIndex = (NewIndex < 0) ? WorldInfo.GRI.PRIArray.Length : -1;
  for (NewIndex=CurrentIndex+Direction; (NewIndex>=0)&&(NewIndex<WorldInfo.GRI.PRIArray.Length); NewIndex=NewIndex+Direction) {
    CPRI = ConPRI (WorldInfo.GRI.PRIArray[NewIndex]);
    if (CPRI != None) {
      if (CycleType == "spectate" && (Controller(CPRI.Owner) != None) && CanSpectate(CPRI) && !CPRI.bOnlySpectator) {
        return CPRI;
      } else if (CycleType == "viewstats" && !CPRI.bOnlySpectator) {
        return CPRI;
      }
    }
  }
  return None; 
}

function bool CanSpectate (PlayerReplicationInfo PRI)
{
  if (PRI == PlayerReplicationInfo) return false; // Exclude self from the cycle
  if (!ConGRI (WorldInfo.GRI).bRoundIsOver) { // You can watch players of the other team between rounds
    if (PRI.Team != PlayerReplicationInfo.Team) return false; // Can only view team mates
  }
  if (Controller(PRI.Owner).Pawn == None) return false; // There must be something to view
  if (Controller(PRI.Owner).IsDead()) return false; // It should be alive, this includes frozen players BTW
  return true;
}
// Kyle: End Spectate System

reliable server function ServerShowMessage (int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2)
{
  ClientShowMessage (Switch, RelatedPRI_1, RelatedPRI_2);
}

reliable client function ClientShowMessage (int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2)
{
  ReceiveLocalizedMessage (class'ConMessage', Switch, RelatedPRI_1, RelatedPRI_2);
}

defaultproperties
{
   Name="ConPlayerController"
}
